#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>

using namespace std;

// typedef function<void()> func_t;
template<class T>
using func_t = function<void(T&)>;

template<class T>
class Thread
{
public:
    Thread(const string &threadname, func_t<T> func ,const T& data)
        : _pid(0), _threadname(threadname), _func(func), isrunning(false) , _data(data)
    {
    }

    // 线程需要执行的函数
    static void *ThreadRoutine(void *arg)
    {
        Thread *pt = (Thread *)arg;

        pt->_func(pt->_data);

        return nullptr;
    }

    // 线程开创建并执行
    bool Start()
    {
        int n = pthread_create(&_pid, nullptr, ThreadRoutine, this);
        if (n == 0)
        {
            isrunning = true;
            // cout << "is strat , is running : " << isrunning << endl;
            return true;
        }
        else
        {
            return false;
        }
    }

    // 线程等待
    bool Join()
    {
        if(!isrunning)  return false;
        return pthread_join(_pid, nullptr);
    }

    bool IsRunning()
    {
        return isrunning;
    }

    string ThreadName()
    {
        return _threadname;
    }

    ~Thread()
    {
    }

private:
    pthread_t _pid;
    string _threadname;
    bool isrunning;
    func_t<T> _func;
    T _data;
};